package com.todo.strategy.online.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.enums.EnableTypeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.common.utils.StringUtils;
import com.todo.component.redis.RedisService;
import com.todo.strategy.common.constant.StrategyOnlineKeyBuild;
import com.todo.strategy.online.application.convert.MemoTemplateConvert;
import com.todo.strategy.online.application.entity.bo.MemoTemplateBO;
import com.todo.strategy.online.application.service.MemoTemplateService;
import com.todo.strategy.online.infrastructure.entity.domain.MemoTemplateDO;
import com.todo.strategy.online.infrastructure.repository.MemoTemplateRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author azhebuxing
 * @date 2024/11/28 02:35
 * @description
 */
@Slf4j
@Service
public class MemoTemplateServiceImpl implements MemoTemplateService {

    @Resource
    private MemoTemplateRepository memoTemplateRepository;
    @Resource
    private RedisService redisService;

    @Override
    public Boolean insertMemoTemplate(MemoTemplateBO memoTemplateBO) {
        if (memoTemplateBO == null) {
            log.error("MemoTemplateService#insertMemoTemplate 新增备忘录数据失败，数据为空");
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR, "数据为空");
        }
        MemoTemplateDO memoTemplateDO = MemoTemplateConvert.convertToMemoTemplateContentDO(memoTemplateBO);
        Boolean insertResult = memoTemplateRepository.insertMemoTemplate(memoTemplateDO);
        if (insertResult) {
            String key = StrategyOnlineKeyBuild.memoTemplateKey(memoTemplateBO.getId());
            redisService.set(key, JSONObject.toJSONString(memoTemplateBO));
        }
        log.info("MemoTemplateService#insertMemoTemplate 新增备忘录数据成功，入参：{},结果：{}", JSONObject.toJSONString(memoTemplateBO), insertResult);
        return insertResult;
    }

    @Override
    public Boolean updateMemoTemplate(MemoTemplateBO memoTemplateBO) {
        if (memoTemplateBO == null) {
            log.error("MemoTemplateService#updateMemoTemplate 更新备忘录数据失败，数据为空");
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR, "数据为空");
        }
        MemoTemplateBO alreadyMemoTemplateBO = queryMemoTemplateById(memoTemplateBO.getId());
        if (alreadyMemoTemplateBO == null) {
            log.error("MemoTemplateService#updateMemoTemplate 更新备忘录数据失败，数据不存在 memoTemplateBO:{}", JSONObject.toJSONString(memoTemplateBO));
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST, "数据不存在");
        }
        if (!alreadyMemoTemplateBO.getUserId().equals(memoTemplateBO.getUserId())) {
            log.error("MemoTemplateService#updateMemoTemplate 更新备忘录数据失败，非创建人数据无法操作 memoTemplateBO:{}", JSONObject.toJSONString(memoTemplateBO));
            throw new BizException(BizErrorCodeEnum.ILLEGAL_OPERATION, "非创建人数据无法操作");
        }
        //todo 考虑用户操作是否许必须要关闭状态？当前不做验证
//        if (EnableTypeEnum.ENABLE.equals(alreadyMemoTemplateBO.getStatus())) {
//            log.error("MemoTemplateService#updateMemoTemplate 更新备忘录数据失败，启用状态下无法操作 memoTemplateBO:{}", JSONObject.toJSONString(memoTemplateBO));
//            throw new BizException(BizErrorCodeEnum.ILLEGAL_OPERATION, "启用状态下无法操作");
//        }
        MemoTemplateDO memoTemplateDO = MemoTemplateConvert.convertToMemoTemplateContentDO(memoTemplateBO);
        Boolean updated = memoTemplateRepository.updateMemoTemplate(memoTemplateDO);
        if (updated) {
            String key = StrategyOnlineKeyBuild.memoTemplateKey(memoTemplateBO.getId());
            redisService.del(key);
        }
        log.info("MemoTemplateService#updateMemoTemplate 更新备忘录数据成功，入参：{},结果：{}", JSONObject.toJSONString(memoTemplateBO), updated);
        return updated;
    }

    @Override
    public Boolean removeMemoTemplateById(Long id) {
        if (id == null || id < 0) {
            log.error("MemoTemplateService#removeMemoTemplateById 删除备忘录数据失败，异常或者为空");
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR, "异常或者为空");
        }
        Boolean removed = memoTemplateRepository.removeMemoTemplateDOById(id);
        if (removed) {
            String key = StrategyOnlineKeyBuild.memoTemplateKey(id);
            redisService.del(key);
        }
        log.info("MemoTemplateService#removeMemoTemplateById 删除备忘录数据成功，入参：{},结果：{}", id, removed);
        return removed;
    }

    @Override
    public MemoTemplateBO queryMemoTemplateById(Long id) {
        if (id == null || id < 0) {
            log.error("MemoTemplateService#queryMemoTemplateById 查询备忘录数据失败，异常或者为空");
            return null;
        }
        String key = StrategyOnlineKeyBuild.memoTemplateKey(id);
        String cached = redisService.get(key);
        if (StringUtils.isNotEmpty(cached)) {
            MemoTemplateBO memoTemplateBO = JSONObject.parseObject(cached, MemoTemplateBO.class);
            log.info("MemoTemplateService#queryMemoTemplateById 缓存查询备忘录数据成功，入参：{},结果：{}", id, JSONObject.toJSONString(memoTemplateBO));
            return memoTemplateBO;
        }
        MemoTemplateDO memoTemplateDO = memoTemplateRepository.queryMemoTemplateDOById(id);
        if (memoTemplateDO == null) {
            log.warn("MemoTemplateService#queryMemoTemplateById 查询备忘录数据失败，数据为空 ID：{}", id);
            return null;
        }
        MemoTemplateBO memoTemplateBO = MemoTemplateConvert.convertToMemoTemplateBO(memoTemplateDO);
        redisService.setOneDay(key, JSONObject.toJSONString(memoTemplateBO));
        log.info("MemoTemplateService#queryMemoTemplateById 数据库查询备忘录数据成功，入参：{},结果：{}", id, JSONObject.toJSONString(memoTemplateBO));
        return memoTemplateBO;
    }

    @Override
    public Boolean updateMemoStatusById(Long id, EnableTypeEnum oldStatus, EnableTypeEnum newStatus) {
        if (id == null || id < 0 || oldStatus == null || newStatus == null || oldStatus == newStatus) {
            log.error("MemoTemplateService#updateMemoStatusById 根据主键更新备忘录状态失败，异常或者为空");
            return false;
        }
        MemoTemplateBO memoTemplateBO = queryMemoTemplateById(id);
        if (memoTemplateBO == null) {
            log.error("MemoTemplateService#updateMemoStatusById 根据主键更新备忘录状态失败，根据Id查询数据不存在 id:{}", id);
            throw new BizException(BizErrorCodeEnum.CONTENT_IS_NULL);
        }
        if (memoTemplateBO.getStatus().equals(newStatus)) {
            log.info("MemoTemplateService#updateMemoStatusById 根据主键更新备忘录状态完成，状态与当前一致，无需更新 id:{}", id);
            return true;
        }
        Boolean updated = memoTemplateRepository.updateMemoStatusById(id, oldStatus.getType(), newStatus.getType());
        if (updated) {
            String key = StrategyOnlineKeyBuild.memoTemplateKey(id);
            redisService.del(key);
        }
        log.info("MemoTemplateService#updateMemoStatusById 根据主键更新备忘录状态完成，Id：{},oldStatus:{},newStatus:{},结果：{}", id, oldStatus, newStatus, updated);
        return updated;
    }

    @Override
    public List<MemoTemplateBO> queryMemoTemplateByUserId(Long userId) {
        if (userId == null || userId < 0) {
            log.error("MemoTemplateService#queryMemoTemplateByUserId 根据用户id查询备忘录数据失败，异常或者为空");
            return Collections.emptyList();
        }
        List<MemoTemplateDO> memoTemplateDOList = memoTemplateRepository.queryMemoTemplateDOByUserId(userId);
        List<MemoTemplateBO> memoTemplateBOS = MemoTemplateConvert.convertTomemoTemplateDOList(memoTemplateDOList);
        List<Long> idList = memoTemplateBOS.stream().map(MemoTemplateBO::getId).collect(Collectors.toList());
        log.info("MemoTemplateService#queryMemoTemplateByUserId 根据用户id查询备忘录数据成功，入参：{},结果IdList：{}", userId, JSONObject.toJSONString(idList));
        return memoTemplateBOS;
    }

    @Override
    public List<MemoTemplateBO> queryMemoTemplateByIdList(List<Long> templateIdList) {
        if (CollectionUtils.isEmpty(templateIdList)) {
            log.warn("MemoTemplateService#queryMemoTemplateByIdList 根据模板id列表查询模板数据失败，异常或者为空");
            return Collections.emptyList();
        }
        List<MemoTemplateBO> memoTemplateBOList = new ArrayList<>();
        List<Long> missIdList = new ArrayList<>();
        for (Long templateId : templateIdList) {
            MemoTemplateBO memoTemplateBO = queryMemoTemplateById(templateId);
            if (memoTemplateBO != null) {
                memoTemplateBOList.add(memoTemplateBO);
            } else {
                missIdList.add(templateId);
            }
        }
        log.info("MemoTemplateService#queryMemoTemplateByIdList 根据模板id列表查询模板数据成功，入参：{},missIdList：{}", JSONObject.toJSONString(templateIdList), JSONObject.toJSONString(missIdList));
        return memoTemplateBOList;
    }

}
